﻿#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>
#include<memory>
#include<functional>
#include<atomic>

using namespace std;

struct Date
{
public:
	int _year;
	int _month;
	int _day;
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}
	Date(Date& a) {
		_day = a._day;
		_month = a._month;
		_year = a._year;
	}
	void Print() {
		cout << _year << _month << _day<<endl;
	}
	~Date()
	{
		cout << "~Date()" << endl;
	}
};

class Fclose
{
public:
    void operator()(FILE* ptr)
    {
        cout << "fclose:" << ptr << endl;
        fclose(ptr);
    }
};

template<class T>
void DeleteArrayFunc(T* ptr)
{
    delete[] ptr;
}

int main()
{
    std::shared_ptr<Date> sp1(new Date);
    std::shared_ptr<Date[]> sp2(new Date[10]);

    // 定制删除器 都可以，相对建议lambda
    std::shared_ptr<Date> sp3(new Date[10], [](Date* ptr) {delete[] ptr; });
    std::shared_ptr<Date> sp4(new Date[5], DeleteArrayFunc<Date>);

    std::shared_ptr<FILE> sp5(fopen("Test.cpp", "r"), Fclose());
    shared_ptr<FILE> sp6(fopen("Test.cpp", "r"), [](FILE* ptr) {
        //cout << "fclose:" << ptr << endl;
        fclose(ptr);
        });

    std::unique_ptr<Date> up1(new Date);
    std::unique_ptr<Date[]> up2(new Date[10]);
    // 定制删除器 建议仿函数
    std::unique_ptr<FILE, Fclose> up3(fopen("Test.cpp", "r"));

    auto fcloseFunc = [](FILE* ptr) {fclose(ptr); };
    std::unique_ptr<FILE, decltype(fcloseFunc)> up4(fopen("Test.cpp", "r"), fcloseFunc);

    return 0;
}







//#include<iostream>
//using namespace std;
//
//struct Date
//{
//public:
//	int _year;
//	int _month;
//	int _day;
//	Date(int year = 1, int month = 1, int day = 1)
//		:_year(year)
//		, _month(month)
//		, _day(day)
//	{}
//	Date(Date& a) {
//		_day = a._day;
//		_month = a._month;
//		_year = a._year;
//	}
//	void Print() {
//		cout << _year << _month << _day<<endl;
//	}
//	~Date()
//	{
//		cout << "~Date()" << endl;
//	}
//};
//#define _CRT_SECURE_NO_WARNINGS 1
//
//#include<iostream>
//#include<memory>
//#include<functional>
//#include<atomic>
//using namespace std;
//
//
//struct Date
//{
//    int _year;
//    int _month;
//    int _day;
//
//    Date(int year = 1, int month = 1, int day = 1)
//        :_year(year)
//        , _month(month)
//        , _day(day)
//    {}
//
//    ~Date()
//    {
//        cout << "~Date()" << endl;
//    }
//};
//
//namespace bit
//{
//    template<class T>
//    class shared_ptr
//    {
//    public:
//        shared_ptr(T* ptr)
//            : _ptr(ptr)
//            , _pcount(new atomic<int>(1))
//        {}
//
//        template<class D>
//        shared_ptr(T* ptr, D del)
//            : _ptr(ptr)
//            , _pcount(new atomic<int>(1))
//            , _del(del)
//        {}
//
//        ~shared_ptr()
//        {
//            if (--(*_pcount) == 0)
//            {
//                //delete _ptr;
//                _del(_ptr);
//                delete _pcount;
//            }
//        }
//
//        shared_ptr(const shared_ptr<T>& sp)
//            : _ptr(sp._ptr)
//            , _pcount(sp._pcount)
//        {
//            (*_pcount)++;
//        }
//
//        // sp1 = sp4;
//        // sp4 = sp4;
//        // sp1 = sp2;
//        shared_ptr<T>& operator=(const shared_ptr<T>& sp)
//        {
//            //if (this != &sp)
//            if (_ptr != sp._ptr)
//            {
//                if (--(*_pcount) == 0)
//                {
//                    delete _ptr;
//                    delete _pcount;
//                }
//
//                _pcount = sp._pcount;
//                _ptr = sp._ptr;
//                ++(*_pcount);
//            }
//
//            return *this;
//        }
//
//        T& operator*()
//        {
//            return *_ptr;
//        }
//
//        T* operator->()
//        {
//            return _ptr;
//        }
//
//        int use_count()
//        {
//            return *_pcount;
//        }
//    private:
//        T* _ptr;
//        //int* _pcount;
//        atomic<int>* _pcount;  // 原子操作
//
//        function<void(T*)> _del = [](T* ptr) {delete ptr; };
//    };
//};
//int main() {
//
//    bit::shared_ptr<Date> p1(new Date);
//  
//}
////int main()
////{
////    bit::shared_ptr<Date> sp1(new Date);
////    bit::shared_ptr<Date> sp2(sp1);
////    // 拷贝构造
////    bit::shared_ptr<Date> sp3 = sp2;
////
////    bit::shared_ptr<Date> sp4(new Date);
////
////    sp1->_year++;
////    sp3->_month++;
////
////    // 赋值拷贝
////    //sp1 = sp4;
////    sp4 = sp4;
////    sp1 = sp2;
////
////	return 0;
////}
//
//class Fclose
//{
//public:
//    void operator()(FILE* ptr)
//    {
//        cout << "fclose:" << ptr << endl;
//        fclose(ptr);
//    }
//};
//
//template<class T>
//void DeleteArrayFunc(T* ptr)
//{
//    delete[] ptr;
//}
//
////int main()
////{
////    bit::shared_ptr<Date> sp1(new Date);
////
////    // 定制删除器 都可以，相对建议lambda
////    bit::shared_ptr<Date> sp3(new Date[10], [](Date* ptr) {delete[] ptr; });
////}
//
////int main()
////{
////    std::shared_ptr<Date> sp1(new Date);
////    std::shared_ptr<Date[]> sp2(new Date[10]);
////
////    // 定制删除器 都可以，相对建议lambda
////    std::shared_ptr<Date> sp3(new Date[10], [](Date* ptr) {delete[] ptr; });
////    std::shared_ptr<Date> sp4(new Date[5], DeleteArrayFunc<Date>);
////
////    std::shared_ptr<FILE> sp5(fopen("Test.cpp", "r"), Fclose());
////    shared_ptr<FILE> sp6(fopen("Test.cpp", "r"), [](FILE* ptr) {
////        //cout << "fclose:" << ptr << endl;
////        fclose(ptr);
////        });
////
////    std::unique_ptr<Date> up1(new Date);
////    std::unique_ptr<Date[]> up2(new Date[10]);
////    // 定制删除器 建议仿函数
////    std::unique_ptr<FILE, Fclose> up3(fopen("Test.cpp", "r"));
////
////    auto fcloseFunc = [](FILE* ptr) {fclose(ptr); };
////    std::unique_ptr<FILE, decltype(fcloseFunc)> up4(fopen("Test.cpp", "r"), fcloseFunc);
////
////    return 0;
////}
//
////int main()
////{
////    std::shared_ptr<Date> sp1(new Date(2024, 9, 11));
////    shared_ptr<Date> sp2 = make_shared<Date>(2024, 9, 11);
////    shared_ptr<Date> sp4;
////
////    // if (sp1.operator bool())
////    if (sp1)
////        cout << "sp1 is not nullptr" << endl;
////
////    //if (!sp4)
////    if (!sp4.operator bool())
////        cout << "sp4 is nullptr" << endl;
////
////    //shared_ptr<Date> sp5 = new Date(2024, 9, 11);
////    //unique_ptr<Date> sp6 = new Date(2024, 9, 11);
////
////    return 0;
////}
//
//struct ListNode
//{
//    int _data;
//
//    /*ListNode* _next;
//    ListNode* _prev;*/
//    /*std::shared_ptr<ListNode> _next;
//    std::shared_ptr<ListNode> _prev;*/
//
//    // 这里改成weak_ptr，当n1->_next = n2;绑定shared_ptr时
//    // 不增加n2的引用计数，不参与资源释放的管理，就不会形成循环引用了
//    std::weak_ptr<ListNode> _next;
//    std::weak_ptr<ListNode> _prev;
//
//    ~ListNode()
//    {
//        cout << "~ListNode()" << endl;
//    }
//};
//
////int main()
////{
////    // 循环引用 -- 内存泄露
////    std::shared_ptr<ListNode> n1(new ListNode);
////    std::shared_ptr<ListNode> n2(new ListNode);
////
////    cout << n1.use_count() << endl;
////    cout << n2.use_count() << endl;
////
////    n1->_next = n2;
////    n2->_prev = n1;
////
////    cout << n1.use_count() << endl;
////    cout << n2.use_count() << endl;
////
////    return 0;
////}
//
////int main()
////{
////    std::shared_ptr<string> sp1(new string("111111"));
////    std::shared_ptr<string> sp2(sp1);
////
////    std::weak_ptr<string> wp = sp1;
////    cout << wp.expired() << endl;
////    cout << wp.use_count() << endl;
////
////    // sp1和sp2都指向了其他资源，则weak_ptr就过期了
////    sp1 = make_shared<string>("222222");
////    cout << wp.expired() << endl;
////    cout << wp.use_count() << endl;
////
////    sp2 = make_shared<string>("333333");
////    cout << wp.expired() << endl;
////    cout << wp.use_count() << endl;
////
////    wp = sp1;
////    //std::shared_ptr<string> sp3 = wp.lock();
////    auto sp3 = wp.lock();
////    cout << wp.expired() << endl;
////    cout << wp.use_count() << endl;
////    sp1 = make_shared<string>("4444444");
////
////    cout << wp.expired() << endl;
////    cout << wp.use_count() << endl;
////
////    return 0;
////}
//
//#include<thread>
//#include<mutex>
//
//struct AA
//{
//    int _a1 = 0;
//    int _a2 = 0;
//
//    ~AA()
//    {
//        cout << "~AA()" << endl;
//    }
//};
//
////int main()
////{
////    bit::shared_ptr<AA> p(new AA);
////    const size_t n = 100000;
////
////    mutex mtx;
////    auto func = [&]()
////    {
////        for (size_t i = 0; i < n; ++i)
////        {
////            // 这里智能指针拷贝会++计数
////            bit::shared_ptr<AA> copy(p);
////            {
////                unique_lock<mutex> lk(mtx);
////                copy->_a1++;
////                copy->_a2++;
////            }
////        }
////    };
////
////    thread t1(func);
////    thread t2(func);
////
////    t1.join();
////    t2.join();
////
////    cout << p->_a1 << endl;
////    cout << p->_a2 << endl;
////
////    cout << p.use_count() << endl;
////
////    return 0;
////}
//
//
////{
////	auto_ptr<Date> ap1(new Date);
////	// 拷⻉时，管理权限转移，被拷⻉对象ap1悬空
////	auto_ptr<Date> ap2(ap1);
////	// 空指针访问，ap1对象已经悬空
////	//ap1->_year++;
////
////	
////	unique_ptr<Date> up1(new Date);
////	// 不⽀持拷⻉
////	//unique_ptr<Date> up2(up1);
////	up1->Print();
////	// ⽀持移动，但是移动后up1也悬空，所以使⽤移动要谨慎
////	unique_ptr<Date> up3(move(up1));
////	shared_ptr<Date> sp1(new Date);
////	// ⽀持拷⻉
////	shared_ptr<Date> sp2(sp1);
////	shared_ptr<Date> sp3(sp2);
////	cout << sp1.use_count() << endl;
////	sp1->_year;
////	cout << sp1->_year << endl;
////	cout << sp2->_year << endl;
////	cout << sp3->_year << endl;
////	// ⽀持移动，但是移动后sp1也悬空，所以使⽤移动要谨慎
////	shared_ptr<Date> sp4(move(sp1));
////	return 0;
////}
////#define _CRT_SECURE_NO_WARNINGS 1
////
////#include<iostream>
////#include<string>
////#include<exception>
////using namespace std;
////
//////double Divide(int a, int b)
//////{
//////	try
//////	{
//////		if (b == 0)
//////		{
//////			string s("Divide by zero condition!");
//////			throw s;
//////
//////			//cout << __FUNCTION__ << ":" << __LINE__ << "行执行" << endl;
//////		}
//////		else
//////		{
//////			return ((double)a / (double)b);
//////		}
//////	}
//////	catch (int errid)
//////	{
//////		cout << errid << endl;
//////	}
//////
//////	cout << __FUNCTION__ << ":" << __LINE__ << "行执行" << endl;
//////
//////	return 0;
//////}
//////
//////void Func()
//////{
//////	int len, time;
//////	cin >> len >> time;
//////
//////	try
//////	{
//////		cout << Divide(len, time) << endl;
//////	}
//////	catch (const char* errmsg)
//////	{
//////		cout << errmsg << endl;
//////	}
//////	cout << __FUNCTION__ << ":" << __LINE__ << "行执行" << endl;
//////}
////
//////int main()
//////{
//////	while (1)
//////	{
//////		try
//////		{
//////			Func();
//////		}
//////		catch (const char* errmsg)
//////		{
//////			cout << errmsg << endl;
//////		}
//////		catch (...) //  任意类型的异常
//////		{
//////			cout << "未知异常" << endl;
//////		}
//////	}
//////
//////	return 0;
//////}
////
////#include<thread>
////
////class Exception
////{
////public:
////	Exception(const string& errmsg, int id)
////		:_errmsg(errmsg)
////		, _id(id)
////	{}
////
////	virtual string what() const
////	{
////		return _errmsg;
////	}
////
////	int getid() const
////	{
////		return _id;
////	}
////protected:
////	string _errmsg;
////	int _id;
////};
////
////class SqlException : public Exception
////{
////public:
////	SqlException(const string& errmsg, int id, const string& sql)
////		:Exception(errmsg, id)
////		, _sql(sql)
////	{}
////
////	virtual string what() const
////	{
////		string str = "SqlException:";
////		str += _errmsg;
////		str += "->";
////		str += _sql;
////		return str;
////	}
////private:
////	const string _sql;
////};
////
////class CacheException : public Exception
////{
////public:
////	CacheException(const string& errmsg, int id)
////		:Exception(errmsg, id)
////	{}
////
////	virtual string what() const
////	{
////		string str = "CacheException:";
////		str += _errmsg;
////		return str;
////	}
////};
////
////class HttpException : public Exception
////{
////public:
////	HttpException(const string& errmsg, int id, const string& type)
////		:Exception(errmsg, id)
////		, _type(type)
////	{}
////
////	virtual string what() const
////	{
////		string str = "HttpException:";
////		str += _type;
////		str += ":";
////		str += _errmsg;
////		return str;
////	}
////
////private:
////	const string _type;
////};
////
////void SQLMgr()
////{
////	if (rand() % 7 == 0)
////	{
////		throw SqlException("权限不足", 100, "select * from name = '张三'");
////	}
////	else
////	{
////		cout << "SQLMgr 调用成功" << endl;
////	}
////}
////
////void CacheMgr()
////{
////	if (rand() % 5 == 0)
////	{
////		throw CacheException("权限不足", 100);
////	}
////	else if (rand() % 6 == 0)
////	{
////		throw CacheException("数据不存在", 101);
////	}
////	else
////	{
////		cout << "CacheMgr 调用成功" << endl;
////	}
////
////	SQLMgr();
////}
////
////void HttpServer()
////{
////	if (rand() % 3 == 0)
////	{
////		throw HttpException("请求资源不存在", 100, "get");
////	}
////	else if (rand() % 4 == 0)
////	{
////		throw HttpException("权限不足", 101, "post");
////	}
////	else
////	{
////		cout << "HttpServer调用成功" << endl;
////	}
////
////	CacheMgr();
////}
////
//////int main()
//////{
//////	srand(time(0));
//////
//////	while (1)
//////	{
//////		this_thread::sleep_for(chrono::seconds(1));
//////
//////		try
//////		{
//////			HttpServer();
//////		}
//////		catch (const Exception& e) 
//////		{
//////			// 多态调用
//////			cout << e.what() << endl;
//////		}
//////		catch (...)
//////		{
//////			cout << "Unkown Exception" << endl;
//////		}
//////	}
//////	return 0;
//////}
////
////void _SendMsg(const string& s)
////{
////	if (rand() % 2 == 0)
////	{
////		throw HttpException("网络不稳定，发送失败", 102, "put");
////	}
////	else if (rand() % 7 == 0)
////	{
////		throw HttpException("你已经不是对象的好友，发送失败", 103, "put");
////	}
////	else
////	{
////		cout << "发送成功" << endl;
////	}
////}
////
////void SendMsg(const string& s)
////{
////	// 发送消息失败，则再重试3次
////	for (size_t i = 0; i < 4; i++)
////	{
////		try
////		{
////			_SendMsg(s);
////			break;
////		}
////		catch (const Exception& e)
////		{
////			if (e.getid() == 102)
////			{
////				if (i == 3)
////					throw;
////
////				cout << "开始第" << i + 1 << "重试" << endl;
////			}
////			else
////			{
////				// 重新抛出
////				throw;
////			}
////		}
////	}
////}
////
//////int main()
//////{
//////	srand(time(0));
//////	string str;
//////	while (cin >> str)
//////	{
//////		try
//////		{
//////			SendMsg(str);
//////		}
//////		catch (const Exception& e)
//////		{
//////			cout << e.what() << endl << endl;
//////		}
//////		catch (...)
//////		{
//////			cout << "Unkown Exception" << endl;
//////		}
//////	}
//////
//////	return 0;
//////}
////
//////double Divide(int a, int b)
//////{
//////	// 当b == 0时抛出异常
//////	if (b == 0)
//////	{
//////		throw "Division by zero condition!";
//////	}
//////	return (double)a / (double)b;
//////}
//////
//////#include<list>
////
//////int main()
//////{
//////	/*try
//////	{
//////		int len, time;
//////		cin >> len >> time;
//////		cout << Divide(len, time) << endl;
//////	}
//////	catch (const char* errmsg)
//////	{
//////		cout << errmsg << endl;
//////	}
//////	catch (...)
//////	{
//////		cout << "Unkown Exception" << endl;
//////	}*/
//////
//////	int i = 0;
//////
//////	cout << noexcept(Divide(1, 2)) << endl;
//////	cout << noexcept(Divide(1, 0)) << endl;
//////	cout << noexcept(++i) << endl;
//////
//////	list<int> lt;
//////
//////	cout << noexcept(lt.begin()) << endl;
//////
//////
//////	return 0;
//////}
////
////double Divide(int a, int b)
////{
////	// 当b == 0时抛出异常
////	if (b == 0)
////	{
////		throw "Divide by zero condition!";
////	}
////	else
////	{
////		return (double)a / (double)b;
////	}
////}
////
////template<class T>
////class SmartPtr
////{
////public:
////	// RAII
////	SmartPtr(T* ptr)
////		:_ptr(ptr)
////	{}
////
////	~SmartPtr()
////	{
////		cout << "delete[] " << _ptr << endl;
////		delete[] _ptr;
////	}
////
////	T& operator*()
////	{
////		return *_ptr;
////	}
////
////	T* operator->()
////	{
////		return _ptr;
////	}
////
////	T& operator[](size_t i)
////	{
////		return _ptr[i];
////	}
////private:
////	T* _ptr;
////};
////
////void Func()
////{
////	SmartPtr<int> sp1 = new int[10];
////	SmartPtr<int> sp2 = new int[10];   // 抛异常呢
////	SmartPtr<int> sp3 = new int[10];   // 抛异常呢
////	SmartPtr<int> sp4 = new int[10];   // 抛异常呢
////	SmartPtr<pair<int, int>> sp5 = new pair<int, int>[10];   // 抛异常呢
////
////	int len, time;
////	cin >> len >> time;
////	cout << Divide(len, time) << endl;
////
////	sp1[5] = 50;
////	sp5->first = 1;
////	sp5->second = 2;
////	cout << sp1[5] << endl;
////}
////
//////int main()
//////{
//////	try
//////	{
//////		Func();
//////	}
//////	catch (const char* errmsg)
//////	{
//////		cout << errmsg << endl;
//////	}
//////	catch (const exception& e)
//////	{
//////		cout << e.what() << endl;
//////	}
//////	catch (...)
//////	{
//////		cout << "未知异常" << endl;
//////	}
//////
//////	return 0;
//////}
////
//////int main()
//////{
//////	SmartPtr<int> sp1 = new int[10];
//////	SmartPtr<int> sp2(sp1);
//////
//////	return 0;
//////}
////
////struct Date
////{
////	int _year;
////	int _month;
////	int _day;
////
////	Date(int year = 1, int month = 1, int day = 1)
////		:_year(year)
////		, _month(month)
////		, _day(day)
////	{}
////
////	~Date()
////	{
////		cout << "~Date()" << endl;
////	}
////};
////
////int main()
////{
////	auto_ptr<Date> ap1(new Date);
////	auto_ptr<Date> ap2(ap1);
////
////	//ap1->_year++;
////
////	unique_ptr<Date> up1(new Date);
////	//unique_ptr<Date> up2(up1);
////
////	//unique_ptr<Date> up3(move(up1));
////
////	shared_ptr<Date> sp1(new Date);
////	shared_ptr<Date> sp2(sp1);
////	shared_ptr<Date> sp3(sp2);
////	cout << sp1.use_count() << endl;
////	sp1->_year++;
////	cout << sp1->_year << endl;
////	cout << sp2->_year << endl;
////	cout << sp3->_year << endl;
////
////	return 0;
////}
